//
//  XHNewsContainerViewController.m
//  XHNewsFramework
//
//  Created by 曾 宪华 on 14-1-24.
//  Copyright (c) 2014年 曾宪华 开发团队(http://iyilunba.com ) 本人QQ:543413507 本人QQ群（142557668）. All rights reserved.
//

#import "XHNewsContainerViewController.h"
#import "XHItemScrollToolBar.h"
#import "XHFountionCommon.h"

#define kXHContentViewTag 10000

@interface XHNewsContainerViewController ()
@property (nonatomic, strong) XHItemScrollToolBar *itemScrollToolBar;
@property (nonatomic, strong) XHEdittingScrollView *scrollView;
@property (nonatomic, strong) NSMutableSet *recycledPages;
@property (nonatomic, strong) NSMutableSet *visiblePages;

- (void)tilePages;
- (void)configurePage:(XHContentView *)contentView forIndex:(int)index;
- (BOOL)isDisplayingPageForIndex:(NSInteger)index;
- (XHContentView *)contentViewForPage:(NSInteger)page;
@end

@implementation XHNewsContainerViewController

#pragma mark - Propertys

- (XHItemScrollToolBar *)itemScrollToolBar {
    if (!_itemScrollToolBar) {
        _itemScrollToolBar = [[XHItemScrollToolBar alloc] initWithFrame:CGRectMake(0, [XHFountionCommon getAdapterHeight], CGRectGetWidth(self.view.bounds), kXHItemScrollToolBarHeight)];
        if (self.items.count)
            _itemScrollToolBar.items = self.items;
    }
    return _itemScrollToolBar;
}

- (void)_reloadDataToItemScrollToolBar {
    self.itemScrollToolBar.items = self.items;
    [self.itemScrollToolBar reloadData];
}

#pragma mark - Life cycle

- (void)loadView {
    [super loadView];
    [self.view setBackgroundColor:[UIColor blackColor]];
	
	CGRect frame = [self scrollViewFrame];
	_scrollView = [[XHEdittingScrollView alloc] initWithFrame:CGRectMake(-1 * self.contentViewPaddingX, 0, frame.size.width + 2 * self.contentViewPaddingX, frame.size.height)];
    _scrollView.decelerationRate = UIScrollViewDecelerationRateFast;
	[_scrollView setScrollsToTop:NO];
	[_scrollView setDelegate:self];
	[_scrollView setShowsHorizontalScrollIndicator:NO];
	[_scrollView setPagingEnabled:YES];
	[_scrollView setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
	[self.view addSubview:self.scrollView];
	[_scrollView setContentSize:CGSizeMake(([self contentViewSize].width + 2 * self.contentViewPaddingX) * [self numberOfContentViews], _scrollView.frame.size.height - frame.origin.y)];
    
    [self.view addSubview:self.itemScrollToolBar];
    [self _reloadDataToItemScrollToolBar];
    
	_recycledPages = [NSMutableSet set];
	_visiblePages = [NSMutableSet set];
	
	[self tilePages];
}

- (void)_setup {
    self.contentViewContentInsetTop = kXHItemScrollToolBarHeight;
}

- (id)init {
    self = [super init];
    if (self) {
        [self _setup];
    }
    return self;
}

- (void)viewDidAppear:(BOOL)animated {
	XHContentView *contentView = [self contentViewAtPage:self.currentPage];
	[contentView pageDidAppear];
}

- (void)viewWillAppear:(BOOL)animated {
	XHContentView *contentView = [self contentViewAtPage:self.currentPage];
	[contentView pageWillAppear];
}

- (void)viewWillDisappear:(BOOL)animated {
	XHContentView *contentView = [self contentViewAtPage:self.currentPage];
	[contentView pageWillDisappear];
}

- (void)viewDidLoad {
    [super viewDidLoad];
	// Do any additional setup after loading the view.
    if ([self respondsToSelector:@selector(automaticallyAdjustsScrollViewInsets)])
        self.automaticallyAdjustsScrollViewInsets = NO;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Resued

- (XHContentView *)dequeueReusablePageWithIdentifier:(NSString*)identifier {
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.identifier == %@", identifier];
	NSSet *filteredSet =[self.recycledPages filteredSetUsingPredicate:predicate];
	XHContentView *page = [filteredSet anyObject];
	if (page) {
		[self.recycledPages removeObject:page];
	}
	return page;
}

- (XHContentView *)contentViewAtPage:(NSInteger)page {
    XHContentView *contentView = (XHContentView *)[self.scrollView viewWithTag:kXHContentViewTag + page];
	return contentView;
}

#pragma mark editing

- (void)onEditingAnimationStopped {
	[self.scrollView setClipsToBounds:YES];
}

- (void)setEditing:(BOOL)isEditing {
    self.isEditing = isEditing;
	
	[UIView beginAnimations:nil context:nil];
	[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
	[UIView setAnimationDuration:0.2];
	[self.scrollView setIsEditing:isEditing];
	[self shouldWiggle:isEditing];
	if (isEditing) {
		[self.scrollView setTransform:CGAffineTransformMakeScale(0.5, 0.5)];
		[self.scrollView setClipsToBounds:NO];
	} else {
		[UIView setAnimationDelegate:self];
		[UIView setAnimationDidStopSelector:@selector(onEditingAnimationStopped)];
		[self.scrollView setTransform:CGAffineTransformMakeScale(1, 1)];
		
	}
    
	[UIView commitAnimations];
}

- (void)shouldWiggle:(BOOL)wiggle {
    for (int i = 0; i < [self numberOfContentViews]; i++) {
		XHContentView *contentView = (XHContentView *)[self.scrollView viewWithTag:kXHContentViewTag + i];
		[contentView shouldWiggle:wiggle];
	}
}

#pragma mark frame and sizes

- (CGRect)scrollViewFrame {
    return CGRectMake(0, 0, [self.view bounds].size.width, [self.view bounds].size.height);
}

- (CGSize)contentViewSize {
    float width = [self scrollViewFrame].size.width;
	if ([self numberOfVisibleContentViews] > 1)
	{
		width = ([self scrollViewFrame].size.width - 2 * self.contentViewPaddingX * ([self numberOfVisibleContentViews] - 1)) / [self numberOfVisibleContentViews];
	}
	
	return CGSizeMake(width,[self scrollViewFrame].size.height);
}

- (NSInteger)numberOfVisibleContentViews {
    return 1;
}

#pragma mark adding and removing page

- (void)addPage {
    [self.scrollView setContentSize:CGSizeMake(([self contentViewSize].width + 2 * self.contentViewPaddingX) * [self numberOfContentViews], self.scrollView.frame.size.width)];
}

- (void)removeCurrentPage {
    if (self.currentPage == [self numberOfContentViews] && self.currentPage != 0) {
		
		XHContentView *contentView = (XHContentView *)[self.scrollView viewWithTag:kXHContentViewTag + self.currentPage];
		[contentView showContentView:NO animated:YES];
		[self removeContentOfPage:self.currentPage];
		
		[contentView performSelector:@selector(showPreviousContentView) withObject:nil afterDelay:0.4];
		[self performSelector:@selector(jumpToPreviousPage) withObject:nil afterDelay:0.6];
	} else if ([self numberOfContentViews] == 0) {
		XHContentView *contentView = (XHContentView *)[self.scrollView viewWithTag:kXHContentViewTag + self.currentPage];
		[contentView showContentView:NO animated:YES];
		[self removeContentOfPage:self.currentPage];
	} else {
		XHContentView *contentView = (XHContentView *)[self.scrollView viewWithTag:kXHContentViewTag + self.currentPage];
		[contentView showContentView:NO animated:YES];
		[self removeContentOfPage:self.currentPage];
		[self performSelector:@selector(pushNextPage) withObject:nil afterDelay:0.4];
	}
}

- (void)removeContentOfPage:(NSInteger)page {
    
}

- (void)pushNextPage {
    [self.scrollView setContentSize:CGSizeMake(([self contentViewSize].width + 2 * self.contentViewPaddingX) * [self numberOfContentViews], self.scrollView.frame.size.width)];
	
	for (int i = self.currentPage; i < [self numberOfVisibleContentViews]; i++) {
		if (self.currentPage < [self numberOfContentViews]) {
			XHContentView *contentView = (XHContentView *)[self.scrollView viewWithTag:kXHContentViewTag + i];
			[contentView showNextContentView];
			[contentView pageWillAppear];
		}
	}
}

- (void)jumpToPreviousPage {
    [self.scrollView setContentSize:CGSizeMake(([self contentViewSize].width + 2 * self.contentViewPaddingX) * [self numberOfContentViews],self.scrollView.frame.size.width)];
}

- (NSInteger)numberOfContentViews {
    return 0;
}

- (void)goToContentView:(NSInteger)index {
    self.scrollView.bounds = CGRectMake(index * self.scrollView.bounds.size.width, self.scrollView.bounds.origin.y, self.scrollView.bounds.size.width, self.scrollView.bounds.size.height);
    
    [self tilePages];
}

#pragma mark reuse contentViews

- (void)tilePages {
    CGRect visibleBounds = [self.scrollView bounds];
	int firstNeededPageIndex = floorf(CGRectGetMinX(visibleBounds) / CGRectGetWidth(visibleBounds)) * [self numberOfVisibleContentViews];
	int lastNeededPageIndex = floorf((CGRectGetMaxX(visibleBounds)-1) / CGRectGetWidth(visibleBounds)) * [self numberOfVisibleContentViews];
    
	firstNeededPageIndex = MAX(firstNeededPageIndex,0);
	lastNeededPageIndex = MIN(lastNeededPageIndex, [self numberOfContentViews]-1) + [self numberOfVisibleContentViews];
	
	if (self.isEditing) firstNeededPageIndex -= 1;
	
	if (firstNeededPageIndex<0) firstNeededPageIndex = 0;
	if (lastNeededPageIndex>=[self numberOfContentViews]) lastNeededPageIndex = [self numberOfContentViews]-1;
	
	self.currentPage = firstNeededPageIndex;
	
	for (XHContentView *contentView in self.visiblePages)
	{
		if (contentView.pageNumber < firstNeededPageIndex || contentView.pageNumber > lastNeededPageIndex)
		{
			[self.recycledPages addObject:contentView];
			[contentView removeFromSuperview];
			[contentView shouldWiggle:NO];
		}
	}
	[self.visiblePages minusSet:self.recycledPages];
	
	for (int index=firstNeededPageIndex; index<=lastNeededPageIndex; index++)
	{
		if (![self isDisplayingPageForIndex:index])
		{
			XHContentView *contentView = [self contentViewForPage:index];
            contentView.tableViewContentInsetTop = [XHFountionCommon getAdapterHeight] + self.contentViewContentInsetTop;
			int x = ([self contentViewSize].width + 2 * self.contentViewPaddingX)*index + self.contentViewPaddingX;
			CGRect panelFrame = CGRectMake(x, 0, [self contentViewSize].width,[self scrollViewFrame].size.height);
			
			[contentView setFrame:panelFrame];
			[contentView setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
			[contentView setDelegate:self];
			[contentView setTag:kXHContentViewTag + index];
			[contentView setPageNumber:index];
			[contentView pageWillAppear];
            
			[self.scrollView addSubview:contentView];
			[self.visiblePages addObject:contentView];
			[contentView shouldWiggle:self.isEditing];
		}
	}
}

- (void)configurePage:(XHContentView *)contentView forIndex:(int)index {
    int x = ([self.view bounds].size.width+2*self.contentViewPaddingX)*index + self.contentViewPaddingX;
	CGRect pageFrame = CGRectMake(x,0,[self.view bounds].size.width,[self.view bounds].size.height);
	[contentView setFrame:pageFrame];
	[contentView setPageNumber:index];
	[contentView pageWillAppear];
}

- (BOOL)isDisplayingPageForIndex:(NSInteger)index {
    for (XHContentView *contentView in self.visiblePages) {
		if (contentView.pageNumber==index) return YES;
	}
	return NO;
}

- (XHContentView *)contentViewForPage:(NSInteger)page {
    static NSString *identifier = @"XHContentTableView";
	XHContentView *contentView = (XHContentView *)[self dequeueReusablePageWithIdentifier:identifier];
	if (contentView == nil)
	{
		contentView = [[XHContentView alloc] initWithIdentifier:identifier];
	}
	return contentView;
}

#pragma mark scroll view delegate

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
	XHContentView *contentView = (XHContentView *)[self.scrollView viewWithTag:kXHContentViewTag + self.currentPage];
	[contentView pageWillDisappear];
}

- (void)scrollViewDidScroll:(UIScrollView*)scrollView {
	//NSLog(@"%@", scrollView_);
	[self tilePages];
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
	
	if (self.currentPage!=self.lastDisplayedPage) {
		XHContentView *contentView = (XHContentView*)[self.scrollView viewWithTag:kXHContentViewTag + self.currentPage];
		[contentView pageDidAppear];
	}
	self.lastDisplayedPage = self.currentPage;
}

// http://stackoverflow.com/a/13858073/3165729
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    if(!decelerate) {
        NSUInteger currentIndex = (NSUInteger)(scrollView.contentOffset.x / scrollView.bounds.size.width);
        
        [scrollView setContentOffset:CGPointMake(scrollView.bounds.size.width * currentIndex, 0) animated:YES];
    }
}

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
    //This is the index of the "page" that we will be landing at
    NSUInteger nearestIndex = (NSUInteger)(targetContentOffset->x / scrollView.bounds.size.width + 0.5f);
    
    //Just to make sure we don't scroll past your content
    nearestIndex = MAX( MIN( nearestIndex, [self numberOfContentViews] - 1 ), 0 );
    
    //This is the actual x position in the scroll view
    CGFloat xOffset = nearestIndex * scrollView.bounds.size.width;
    
    //I've found that scroll views will "stick" unless this is done
    xOffset = xOffset==0?1:xOffset;
    
    //Tell the scroll view to land on our page
    *targetContentOffset = CGPointMake(xOffset, targetContentOffset->y);
}

#pragma mark - XHContentView delegate

- (NSString *)contentView:(XHContentView *)contentView titleForHeaderInPage:(NSInteger)pageNumber section:(NSInteger)section {
    return [NSString stringWithFormat:@"Page %i Section %i", pageNumber, section];
}

- (UITableViewCell *)contentView:(XHContentView *)contentView cellForRowAtIndexPath:(XHPageIndexPath *)indexPath {
    return nil;
}

- (NSInteger)contentView:(XHContentView *)contentView numberOfRowsInPage:(NSInteger)page section:(NSInteger)section {
    return 0;
}

@end
